<template>
  <div class="app-container">
    <el-form>
      <div style="float: right">
        <el-button type="primary" size="small" @click="popNewEnv">添加环境</el-button>
        <el-button type="primary" size="small" @click="popEditEnv">编辑环境</el-button>
      </div>
      <el-tabs
        v-model="selectedTab"
        type="card"
        closable
        @tab-remove="removeEnv"
        @tab-click="selectEnv"
      >
        <el-tab-pane
          v-for="(item) in envTabs"
          :key="item.envId"
          :label="item.envName"
          :name="item.envId"
        >
          <span slot="label" style="padding: 8px">{{ item.envName }}</span>

          <el-collapse v-model="activeCollapse">
            <!-- 数据库配置 -->
            <el-collapse-item title="数据库配置" name="jdbc">
              <el-table ref="singleTable" :data="jdbcTableData" style="width: 100%">
                <el-table-column label="属性名" prop="propName" min-width="15%">
                  <template slot-scope="scope">
                    <div>
                      <span>{{ scope.row.propName }}</span>
                    </div>
                  </template>
                </el-table-column>
                <el-table-column label="属性key" prop="propKey" min-width="20%">
                  <template slot-scope="scope">
                    <div>
                      <span>{{ scope.row.propKey }}</span>
                    </div>
                  </template>
                </el-table-column>
                <el-table-column
                  label="属性Value"
                  prop="propValue"
                  min-width="65%"
                  :render-header="tableHeadIcon"
                >
                  <template slot-scope="scope">
                    <el-input
                      v-if="scope.row.propValueEditable"
                      v-model="scope.row.propValue"
                      size="mini"
                      @blur="blurColumn(scope.row, 'propValue')"
                    />
                    <span
                      v-else
                      @click="editColumn(scope.row, 'propValue', $event)"
                      :style="scope.row.propValueEmpty?'color: #cccccc':''"
                    >{{ scope.row.propValue }}</span>
                  </template>
                </el-table-column>
              </el-table>
            </el-collapse-item>
            <!-- Redis配置 -->
            <el-collapse-item title="Redis配置" name="redis">
              <el-table ref="singleTable" :data="redisTableData" style="width: 100%">
                <el-table-column label="属性名" prop="propName" min-width="15%">
                  <template slot-scope="scope">
                    <div>
                      <span>{{ scope.row.propName }}</span>
                    </div>
                  </template>
                </el-table-column>
                <el-table-column label="属性key" prop="propKey" min-width="20%">
                  <template slot-scope="scope">
                    <div>
                      <span>{{ scope.row.propKey }}</span>
                    </div>
                  </template>
                </el-table-column>
                <el-table-column
                  label="属性Value"
                  prop="propValue"
                  min-width="65%"
                  :render-header="tableHeadIcon"
                >
                  <template slot-scope="scope">
                    <el-input
                      v-if="scope.row.propValueEditable"
                      v-model="scope.row.propValue"
                      size="mini"
                      @blur="blurColumn(scope.row, 'propValue')"
                    />
                    <span
                      v-else
                      @click="editColumn(scope.row, 'propValue', $event)"
                      :style="scope.row.propValueEmpty?'color: #cccccc':''"
                    >{{ scope.row.propValue }}</span>
                  </template>
                </el-table-column>
              </el-table>
            </el-collapse-item>
            <!-- MongoDB配置 -->
            <el-collapse-item title="MongoDB配置" name="mongodb">
              <el-table ref="singleTable" :data="mongoDBTableData" style="width: 100%">
                <el-table-column label="属性名" prop="propName" min-width="15%">
                  <template slot-scope="scope">
                    <div>
                      <span>{{ scope.row.propName }}</span>
                    </div>
                  </template>
                </el-table-column>
                <el-table-column label="属性key" prop="propKey" min-width="20%">
                  <template slot-scope="scope">
                    <div>
                      <span>{{ scope.row.propKey }}</span>
                    </div>
                  </template>
                </el-table-column>
                <el-table-column
                  label="属性Value"
                  prop="propValue"
                  min-width="65%"
                  :render-header="tableHeadIcon"
                >
                  <template slot-scope="scope">
                    <el-input
                      v-if="scope.row.propValueEditable"
                      v-model="scope.row.propValue"
                      size="mini"
                      @blur="blurColumn(scope.row, 'propValue')"
                    />
                    <span
                      v-else
                      @click="editColumn(scope.row, 'propValue', $event)"
                      :style="scope.row.propValueEmpty?'color: #cccccc':''"
                    >{{ scope.row.propValue }}</span>
                  </template>
                </el-table-column>
              </el-table>
            </el-collapse-item>
            <!-- 自定义配置 -->
            <el-collapse-item name="user_defined">
              <template slot="title">
                <span>自定义配置</span>
                <el-button type="primary" size="mini" class="prop-add" @click.stop="addProp">添加配置</el-button>
              </template>
              <el-table ref="singleTable" :data="userDefinedTableData" style="width: 100%">
                <el-table-column
                  label="属性名"
                  prop="propName"
                  min-width="15%"
                  :render-header="tableHeadIcon"
                >
                  <template slot-scope="scope">
                    <el-input
                      v-if="scope.row.propNameEditable"
                      v-model="scope.row.propName"
                      size="mini"
                      @blur="blurColumn(scope.row, 'propName')"
                    />
                    <span
                      v-else
                      @click="editColumn(scope.row, 'propName', $event)"
                      :style="scope.row.propNameEmpty?'color: #cccccc':''"
                    >{{ scope.row.propName }}</span>
                  </template>
                </el-table-column>
                <el-table-column
                  label="属性key"
                  prop="propKey"
                  min-width="20%"
                  :render-header="tableHeadIcon"
                >
                  <template slot-scope="scope">
                    <el-input
                      v-if="scope.row.propKeyEditable"
                      v-model="scope.row.propKey"
                      size="mini"
                      @blur="blurColumn(scope.row, 'propKey')"
                    />
                    <span
                      v-else
                      @click="editColumn(scope.row, 'propKey', $event)"
                      :style="scope.row.propKeyEmpty?'color: #cccccc':''"
                    >{{ scope.row.propKey }}</span>
                  </template>
                </el-table-column>
                <el-table-column
                  label="属性Value"
                  prop="propValue"
                  min-width="60%"
                  :render-header="tableHeadIcon"
                >
                  <template slot-scope="scope">
                    <el-input
                      v-if="scope.row.propValueEditable"
                      v-model="scope.row.propValue"
                      size="mini"
                      @blur="blurColumn(scope.row, 'propValue')"
                    />
                    <span
                      v-else
                      @click="editColumn(scope.row, 'propValue', $event)"
                      :style="scope.row.propValueEmpty?'color: #cccccc':''"
                    >{{ scope.row.propValue }}</span>
                  </template>
                </el-table-column>
                <el-table-column min-width="5%">
                  <template slot-scope="scope">
                    <el-button
                      type="danger"
                      size="mini"
                      icon="el-icon-delete"
                      circle
                      @click="delProp(scope.$index, scope.row)"
                    />
                  </template>
                </el-table-column>
              </el-table>
            </el-collapse-item>
          </el-collapse>
        </el-tab-pane>
      </el-tabs>
    </el-form>
    <el-dialog title="环境配置" :visible.sync="envDialogVisible" width="500px">
      <el-form>
        <el-form-item label="环境名称" label-width="100px">
          <el-input
            v-model="envConfig.envName"
            placeholder="xx项目xx环境"
            clearable
            style="width: 300px"
            maxlength="12"
          />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="envDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="saveEnv()">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { requestConfigApi } from '@/api/config/propConfig'

export default {
  data() {
    return {
      envDialogVisible: false,
      // 环境配置弹窗绑定数据
      envConfig: {
        envId: null,
        envName: null
      },
      // 选中的环境
      selectedTab: null,
      // 环境配置tab数据
      envTabs: [],
      // 折叠面板激活
      activeCollapse: ['jdbc', 'redis', 'mongodb', 'user_defined'],
      // jdbc配置表格的绑定数据
      jdbcTableData: [],
      // redis配置表格的绑定数据
      redisTableData: [],
      // mongoDB配置表格的绑定数据
      mongoDBTableData: [],
      // 自定义配置表格的绑定数据
      userDefinedTableData: []
    }
  },
  created() {
    this.fetchData()
  },
  methods: {
    // 刷新页面的数据，加载环境配置数据，加载激活环境的属性配置数据
    fetchData() {
      requestConfigApi('findAllEnv', {}).then(response => {
        // console.log(response.data)
        if (response.data === null || response.data.envList === null || response.data.envList.length === 0) {
          return
        }
        response.data.envList.forEach((envInfo, index) => {
          this.envTabs.push({
            envName: envInfo.envName,
            envId: envInfo.envId + ''
          })
        })
        if (this.envTabs.length > 0) {
          this.selectedTab = this.envTabs[0].envId
          this.loadPropData(this.envTabs[0].envId)
        }
      })
    },
    // 加载某环境的属性配置数据
    loadPropData(envId) {
      const param = {
        'id': envId
      }
      requestConfigApi('findPropByEnv', param).then(response => {
        for (const propGroupName in response.data.propConfigMap) {
          response.data.propConfigMap[propGroupName].forEach(prop => {
            if (propGroupName === 'jdbc') {
              this.initPropTable(this.jdbcTableData, prop)
            } else if (propGroupName === 'redis') {
              this.initPropTable(this.redisTableData, prop)
            } else if (propGroupName === 'mongodb') {
              this.initPropTable(this.mongoDBTableData, prop)
            } else if (propGroupName === 'user_defined') {
              this.initPropTable(this.userDefinedTableData, prop)
            }
          })
        }
      })
    },
    // 构造表格的每一行数据
    initPropTable(tableData, prop) {
      tableData.push({
        propId: prop.propId,
        propGroup: prop.propGroup,
        propName: this.isEmpty(prop.propName) ? '请输入' : prop.propName,
        propKey: this.isEmpty(prop.propKey) ? '请输入' : prop.propKey,
        propValue: this.isEmpty(prop.propValue) ? '请输入' : prop.propValue,
        propNameEmpty: this.isEmpty(prop.propName),
        propKeyEmpty: this.isEmpty(prop.propKey),
        propValueEmpty: this.isEmpty(prop.propValue),
        propNameEditable: false,
        propKeyEditable: false,
        propValueEditable: false
      })
    },
    // 添加环境弹窗
    popNewEnv() {
      this.envDialogVisible = true
      this.envConfig.envName = null
      this.envConfig.envId = null
    },
    // 编辑环境弹窗
    popEditEnv() {
      this.envTabs.forEach((item, index) => {
        if (item.envId == this.selectedTab) {
          this.envConfig.envName = item.envName
          this.envConfig.envId = item.envId
        }
      })
      this.envDialogVisible = true
    },
    // 保存环境
    saveEnv() {
      if (this.envConfig.envName === null || this.envConfig.envName.trim() === '') {
        this.$message.error('环境名称不能为空')
        return
      }
      const param = {
        id: this.envConfig.envId,
        envName: this.envConfig.envName
      }
      requestConfigApi('saveEnv', param).then(response => {
        if (response.code === '200') {
          if (this.envConfig.envId === null) {
            this.envTabs.push({
              envName: this.envConfig.envName,
              envId: response.data.id + ''
            })
            this.selectedTab = response.data.id + ''
            this.selectEnv()
          } else {
            this.envTabs.forEach((item, index) => {
              if (item.envId == response.data.id) {
                item.envName = this.envConfig.envName
              }
            })
          }
          this.envConfig = {
            envId: null,
            envName: null
          }
          this.envDialogVisible = false
        } else {
          this.$message.error(response.message)
        }
      })
    },
    // 删除环境
    removeEnv(targetTab) {
      let tabName
      this.envTabs.forEach(tab => {
        if (tab.envId === targetTab) {
          tabName = tab.envName
        }
      })
      this.$confirm('确定删除"' + tabName + '"环境吗？', '删除确认', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        const param = {
          'id': targetTab
        }
        requestConfigApi('delEnv', param).then(response => {
          for (var i = 0; i < this.envTabs.length; i++) {
            if (this.envTabs[i].envId === targetTab) {
              this.envTabs.splice(i, 1)
              if (targetTab === this.selectedTab) {
                const nextTab = this.envTabs[i + 1] || this.envTabs[i - 1]
                this.selectedTab = nextTab.envId
              }
              break
            }
          }
          this.selectEnv()
        })
      }).catch(() => {
      })
    },
    // 选中环境，加载属性配置
    selectEnv() {
      // console.log(this.selectedTab)
      this.jdbcTableData = new Array(0)
      this.redisTableData = new Array(0)
      this.mongoDBTableData = new Array(0)
      this.userDefinedTableData = new Array(0)
      this.loadPropData(this.selectedTab)
    },
    // 点击属性配置，开始编辑
    editColumn(row, columnName, event) {
      if (row[columnName + 'Editable']) {
        return
      }
      row[columnName + 'Editable'] = true
      if (row[columnName] === '请输入') {
        row[columnName] = null
      }
      // 选中内容，便于修改
      const div = event.currentTarget.parentElement
      this.$nextTick(function () {
        div.children[0].children[0].select()
      })
    },
    // 属性配置输入框失去焦点，保存编辑的内容
    blurColumn(row, columnName) {
      // console.log(row)
      const param = {
        'id': row.propId,
        'envId': this.selectedTab,
        'propGroup': row.propGroup,
        'propName': row.propName === '请输入' ? null : row.propName,
        'propKey': row.propKey === '请输入' ? null : row.propKey,
        'propValue': row.propValue === '请输入' ? null : row.propValue
      }
      // console.log(param)
      requestConfigApi('saveProp', param).then(response => {
        if (response.code === '200') {
          row.propId = response.data.id
          row[columnName + 'Editable'] = false
          if (this.isEmpty(row[columnName])) {
            row[columnName] = '请输入'
            row[columnName + 'Empty'] = true
          } else {
            row[columnName + 'Empty'] = false
          }
        } else {
          this.$message.error(response.message)
        }
      })
    },
    // 添加自定义属性配置
    addProp() {
      this.userDefinedTableData.push({
        propId: null,
        propGroup: 'user_defined',
        propName: '请输入',
        propKey: '请输入',
        propValue: '请输入',
        propNameEmpty: true,
        propKeyEmpty: true,
        propValueEmpty: true,
        propNameEditable: false,
        propKeyEditable: false,
        propValueEditable: false
      })
    },
    // 删除自定义属性配置
    delProp(index, row) {
      this.$confirm('确定要删除这个配置吗？', '删除确认', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        if (row.propId === null) {
          this.userDefinedTableData.splice(index, 1)
          return
        }
        const param = {
          'id': row.propId
        }
        requestConfigApi('delProp', param).then(response => {
          if (response.code === '200') {
            this.userDefinedTableData.splice(index, 1)
          } else {
            this.$message.error(response.message)
          }
        })
      }).catch(() => {
      })
    },
    // 自定义表头，加上一个可编辑的图标
    tableHeadIcon(h, { column }) {
      return h(
        'div', [
          h('span', column.label),
          h('i', {
            class: 'el-icon-edit',
            style: 'color: blue; margin-left: 5px;'
          })
        ]
      )
    },
    isEmpty(str) {
      return str === null || str === undefined || str === ''
    }
  }
}
</script>
<style>
.el-tabs--card > .el-tabs__header {
  width: 90%;
}
.prop-add {
  margin-left: 10px;
  height: 24px;
  line-height: 6px;
}
</style>

